home *** CD-ROM | disk | FTP | other *** search
-
- * Imploder Style Decrunch by Cath of LSD *
- * Taken from the depths of IEEE magazine *
-
- * SProModule was extended from here ! *
-
- * Tester!
-
- ifne 0
- lea Data(pc),a0
- lea buffer(pc),a1
- bsr IMPL_Decr
- clr.l d0
- rts
-
- endc
-
- ID equ 'IMP!' ; ID suggested by ieee and used by a cruncher?
-
- * IMP! Scrunch Pro (SPMO) Module Decruncher by Cath of LsD *
-
-
- STRUCTURE SProModule,0
- ULONG sm_CrunchedAddr ; The address of the crunched data
- ULONG sm_CrunchedSize ; The size of the crunched data
- ULONG sm_DecrAddr ; This is used by the module to pass back data
- ULONG sm_DecrSize ; This is used by the module to pass back data
- ULONG sm_Reserved1 ; Guess (For future use, currently set to zero)
- ULONG sm_Reserved2 ; Guess (For future use, currently set to zero)
- ULONG sm_Informer ; This is set to the addrress to shove data to
- ; ie _custom.color00
-
- LABEL spro_SIZEOF
-
- ; Anything beyond this is currently private!
-
- ; ............X ; Private data
-
-
- SM_NOMEMORY equ $DEADFFF0 ; no memory for crunch/decrunch
- SM_UNRECOGNISED equ $DEADFFF1 ; not a recognised buffer
- SM_UNKNOWN equ $DEADFFF2 ; unknown error
- SM_NODECRUNCH equ $DEADFFF3 ; this module is crunch only
- SM_NOCRUNCH equ $DEADFFF4 ; this module is decrunch only
- SM_COULDNTCRUNCH equ $DEADFFF5 ; actual cruncher couldn't decrunch ?
- SM_COULDNTDECR equ $DEADFFF6 ; actual decruncher couldn't crunch
-
- dc.b 'SPMO' ; The third sprmo decr module
-
- Start
- tst.l sm_DecrAddr(a0) ; Is this a DeCrunch ?
- beq.s DeCrunch ; Yes
-
- ; This is no cruncher, baby!
-
- NoCruncher
- move.l #-1,sm_DecrAddr(a0) ; Tell scrunch about the error
- move.l #SM_NOCRUNCH,sm_DecrSize(a0) ; No crunch possible
- rts
-
- DeCrunch
- move.l (a0),a1 ; Get address of crunched data
- cmp.l #ID,(a1) ; Is this valid data
- beq.s YesValidData ; Yes its Ok
-
- move.l #-1,sm_DecrAddr(a0) ; Tell scrunch about error
- move.l #SM_UNRECOGNISED,sm_DecrSize(a0) ; Error code
- rts
-
- YesValidData
-
- move.l 4(a1),sm_DecrSize(a0) ; Get size of decrunched data
- move.l 4.w,a6
- movem.l a0/a1,-(sp)
- move.l 4(a1),d0 ; Get size of decrunched data
- move.l #MEMF_PUBLIC|MEMF_CLEAR,d1; Mem flags
- jsr _LVOAllocMem(a6) ; Allocate mem
- movem.l (sp)+,a0/a1 ; Restore regs
- tst.l d0
- bne.s MemOk ; Allocated Ok,
-
- ; Not enough memory for decrunch !
-
- move.l #-1,sm_DecrAddr(a0)
- move.l #SM_NOMEMORY,sm_DecrSize(a0)
- rts
-
- MemOk
- move.l d0,sm_DecrAddr(a0) ; Set address of decrunched data
- ; sm_DecrSize has already been set
-
- movem.l a0-a6/d1-d7,-(sp) ; Save all regs!
-
- move.l sm_DecrAddr(a0),a1 ; Set decrunch address
- move.l sm_CrunchedAddr(a0),a0 ; Set crunched address (doesn't need offset)
- ; no point removing as its negligble)
-
- * This decruncher requires the crunched buffer to be in the deCrunch buffer
- * so we need to move the original crunched data
-
- * +---------------------------------Decrunch Mem area -------------+
- * +-----------Crunched Data ------+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX+
- * ^ filled in by decruncher
-
- movem.l a0-a6/d0-d7,-(sp)
-
- move.l 8(a0),d0 ; Get size of crunched data
- add.l #80,d0 ; And a bit more for luck (to cover table)
- move.l 4.w,a6 ; Execbase
- jsr _LVOCopyMemQuick(a6) ; Copymem
-
- movem.l (sp)+,a0-a6/d0-d7
-
- move.l a1,a0 ; Set both addresses to same area
-
- bsr.s IMPL_Decr ; Decrunch the Data
- movem.l (sp)+,a0-a6/d1-d7 ; Ok
-
- beq.s DecrError ; There was an error!
-
- rts ; Return to Scrunch Ok!
-
- DecrError
- move.l sm_DecrAddr(a0),a1 ; An error in the decrunch
- move.l sm_DecrSize(a0),d0
- move.l 4.w,a6
- move.l a0,-(sp)
- jsr _LVOFreeMem(a6) ; So free the memory
- move.l (sp)+,a0
-
- move.l #-1,sm_DecrAddr(a0)
- move.l #SM_COULDNTDECR,sm_DecrSize(a0) ; Tell scrunch about the error
- rts
-
-
- ; this is the actual decruncher
-
- Leave
- moveq #0,d0 ; setup bad ret code
- rts
-
- IMPL_Decr *******************************
- * A0-ptr to buffer,A0 ptr to out buffer *
- *****************************************
-
- * Taken from the depths of IEEE magazine
- * This is basically the same routine as imploder uses (its where it gets its name from, the
- * program not the algorithm and its used widely). Its based on LZW compression
- * this is the basis on which AT&T and BT based their own compression systems on
- * other programs that use it are lha and pkware
-
- Decompress
- cmp.l #ID,(a0) ; Check imploder header string
- ; this is the ISO/IEEE string used
- bne.s Leave
-
- movem.l d2-d5/a2-a5,-(sp) ; save blasted regs
-
- move.l a0,a3 ; get copy of buffer ptr
- move.l a0,a5 ; get copy of destination buffer ptr
-
- tst.l (a0)+ ; Skip IMP! ID
-
- add.l (a0)+,a5 ; Get decrunched length
-
- add.l (a0)+,a3 ; Get crunched length
-
- move.l a3,a2 ; A2->End of crunched buffer
- ; A5->End of Complete buffer
-
- move.l (a2)+,-(a0) ; Get data table
- move.l (a2)+,-(a0)
- move.l (a2)+,-(a0)
- move.l (a2)+,d2
- move.w (a2)+,d3
-
- bmi.s DontFix
-
- subq.l #1,a3 ; Ptr to Buffer End - 1
-
- DontFix
-
- lea -$1C(sp),sp ; Get some stack space
-
- move.l sp,a1 ; point to it
-
- moveq #6,d0 ; rest of table
- MoveTable
- move.l (a2)+,(a1)+
- dbra d0,MoveTable
-
- move.l sp,a1 ; point to source again
-
- StartDecr
- tst.l d2 ; Anything to store ?
- beq.s Nope ; No
-
- CopyLoop
- move.b -(a3),-(a5) ; Store decrunched data
- subq.l #1,d2 ; Decrement byte count
- bne.s CopyLoop ; Any more to do
-
- Nope
- cmp.l a5,a0 ; Have we reached begininng of buffer
- bcs.s DoDecrunch ; Still to decrunch
-
-
- lea $1C(sp),sp ; free stack space
-
- moveq #-1,d0 ; Set return code as good
-
- cmp.l a3,a0 ; Do the end addresses match?
- beq.s MatchOk
-
- moveq #0,d0 ; Set return code as bad
-
- MatchOk
- movem.l (sp)+,d2-d5/a2-a5
- tst.l d0 ; Save returned prog checking
- rts ; Return code
-
-
- DoDecrunch
- add.b d3,d3 ; doubler
- bne.s DOA
- move.b -(a3),d3
- addx.b d3,d3
-
- DOA
- bcc.s SetupDecodeTable_4
- add.b d3,d3
- bne.s Extract_1
- move.b -(a3),d3
- addx.b d3,d3
-
- Extract_1
- bcc.s SetupDecodeTable_3
- add.b d3,d3
- bne.s Extract_2
- move.b -(a3),d3
- addx.b d3,d3
-
- Extract_2
- bcc.s SetupDecodeTable_2
- add.b d3,d3
- bne.s Extract_3
- move.b -(a3),d3
- addx.b d3,d3
-
- Extract_3
- bcc.s SetupDecodeTable_1
- moveq #0,d4
- add.b d3,d3
- bne.s Extract_4
- move.b -(a3),d3
- addx.b d3,d3
-
- Extract_4
- bcc.s Extract_5
- move.b -(a3),d4
- moveq #3,d0
- subq.b #1,d4
- bra.s DecodeTable_1
-
- Extract_5
- add.b d3,d3
- bne.s Extract_6
- move.b -(a3),d3
- addx.b d3,d3
-
- Extract_6
- addx.b d4,d4
- add.b d3,d3
- bne.s Extract_7
- move.b -(a3),d3
- addx.b d3,d3
-
- Extract_7
- addx.b d4,d4
- add.b d3,d3
- bne.s Extract_8
- move.b -(a3),d3
- addx.b d3,d3
-
- Extract_8
- addx.b d4,d4
- addq.b #5,d4
- moveq #3,d0
- bra.s DecodeTable_1
-
- SetupDecodeTable_1
- moveq #4,d4
- moveq #3,d0
- bra.s DecodeTable_1
-
- SetupDecodeTable_2
- moveq #3,d4
- moveq #2,d0
- bra.s DecodeTable_1
-
- SetupDecodeTable_3
- moveq #2,d4
- moveq #1,d0
- bra.s DecodeTable_1
-
- SetupDecodeTable_4
- moveq #1,d4
- moveq #0,d0
-
- DecodeTable_1
- moveq #0,d5
- move.w d0,d1
- add.b d3,d3
- bne.s NoFetch1
- move.b -(a3),d3
- addx.b d3,d3
-
- NoFetch1
- bcc.s DoTable
- add.b d3,d3
- bne.s NoFetch2
- move.b -(a3),d3
- addx.b d3,d3
-
- NoFetch2
- bcc.s NoEntry
- move.b ImpTable(pc,d0.w),d5
- addq.b #8,d0
- bra.s DoTable
-
- NoEntry
- moveq #2,d5 ; Set default
- addq.b #4,d0
-
- DoTable
- move.b RunTable(pc,d0.w),d0 ; ptr to run table
-
- _DoTable
- add.b d3,d3
- bne.s NoFetch3
- move.b -(a3),d3
- addx.b d3,d3
-
- NoFetch3
- addx.w d2,d2
- subq.b #1,d0
- bne.s _DoTable
- add.w d5,d2
- moveq #0,d5
- move.l d5,a2
- move.w d1,d0
- add.b d3,d3
- bne.s NoFetch4
- move.b -(a3),d3
- addx.b d3,d3
-
- NoFetch4
- bcc.s NoFetch5
- add.w d1,d1
- add.b d3,d3
- bne.s NoFetch5a
- move.b -(a3),d3
- addx.b d3,d3
-
- NoFetch5a
- bcc.s DoAgain
-
- move.w 8(a1,d1.w),a2
- addq.b #8,d0
- bra.s NoFetch5
-
- DoAgain
- move.w (a1,d1.w),a2
- addq.b #4,d0
-
- NoFetch5
- move.b 16(a1,d0.w),d0
-
- DoBytes
- add.b d3,d3
- bne.s NoFetch7
- move.b -(a3),d3
- addx.b d3,d3
-
- NoFetch7
- addx.l d5,d5
- subq.b #1,d0
- bne.s DoBytes
-
- addq.w #1,a2
- add.l d5,a2
- add.l a5,a2
-
- CopyLoop2
- move.b -(a2),-(a5) ; Store bytes
- dbra d4,CopyLoop2
-
- bra StartDecr ; Continue, and check for end
-
-
- * --------------- Data Area ------------- *
-
- ImpTable
- dc.b 6,10,10,18
-
- RunTable
- dc.b 1,1,1,1,2,3,3,4,4,5,7,14 ; Length of runs
-
- ifne 0
-
- Data
- incbin spmo:test.impl
- buffer
- dcb.b 500000,0
- endc
-
- END
-